module mdio_wr(
	input	wire		sclk,//125M
	input	wire		rst_n,
	input	wire		w_en,// one period valid sclk
	input	wire		r_en,// one period valid sclk
	input	wire	[4:0]	phy_addr,//one period valid sclk
	input	wire	[4:0]	reg_addr,//one period valid sclk
	input	wire	[15:0]	w_data,
	output	reg	[15:0]	r_data,
	output	reg		rd_v ,
	output	reg		busy,
	inout	wire		mdio,
	output	reg		mdc	
);
parameter	FREQ_DIV	=6-1;
parameter	RISE_NUM	=((FREQ_DIV+1)/2)-1;
parameter	FALL_NUM	=FREQ_DIV;
parameter	END_NUM		=65;

reg	[7:0]	div_cnt;
reg		rise_flag,fall_flag;
reg		shift_flag,r_shift_flag,w_flag,r_flag,end_flag;
reg	[32:0]	shift_data;
reg	[6:0]	base_cnt;
reg		oe;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		div_cnt<='d0;
	else if(div_cnt==FREQ_DIV)
		div_cnt<='d0;
	else div_cnt<=div_cnt+1'b1;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		rise_flag<=1'b0;
	else if(div_cnt==RISE_NUM)
		rise_flag<=1'b1;
	else rise_flag<=1'b0;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		fall_flag<=1'b0;
	else if(div_cnt==FALL_NUM)
		fall_flag<=1'b1;
	else	fall_flag<=1'b0;
	
always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		mdc<=1'b1;
	else if(rise_flag==1'b1)
		mdc<=1'b0;
	else if(fall_flag==1'b1)
		mdc<=1'b1;
always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		busy<=1'b0;
	else if(w_en==1'b1 || r_en==1'b1)
		busy<=1'b1;
	else if(end_flag==1'b1)
		busy<=1'b0; 
always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		w_flag<=1'b0;
	else if(w_en==1'b1 && busy==1'b0)
		w_flag<=1'b1;
	else if(w_flag==1'b1 && end_flag==1'b1)
		w_flag<=1'b0;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		r_flag<=1'b0;
	else if(r_en==1'b1 && busy==1'b0)
		r_flag<=1'b1;
	else if(r_flag==1'b1 && end_flag==1'b1)
		r_flag<=1'b0;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		base_cnt<='d0;
	else if(end_flag==1'b1)
		base_cnt<='d0;
	else if((w_flag==1'b1 || r_flag==1'b1) && rise_flag==1'b1)
		base_cnt<=base_cnt+1'b1;
		
always @*
	if(base_cnt==END_NUM && rise_flag==1'b1)
		end_flag<=1'b1;
	else 
		end_flag<=1'b0;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		shift_flag<=1'b0;
	else if(w_flag==1'b1 && base_cnt =='d31 && rise_flag==1'b1)
		shift_flag<=1'b1;
	else if(w_flag==1'b1 && end_flag==1'b1)
		shift_flag<=1'b0;
	else if(r_flag==1'b1 && base_cnt =='d31 && rise_flag==1'b1)
		shift_flag<=1'b1;
	else if(r_flag==1'b1 && base_cnt =='d46 && rise_flag==1'b1)
		shift_flag<=1'b0;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		oe<=1'b0;
	else if(base_cnt=='d0 && w_flag==1'b1 && rise_flag==1'b1)
		oe<=1'b1;
	else if(base_cnt=='d64 && w_flag==1'b1 && rise_flag==1'b1)
		oe<=1'b0;
	else if(base_cnt=='d0 && r_flag==1'b1 && rise_flag==1'b1)
		oe<=1'b1;
	else if(base_cnt=='d46 && r_flag==1'b1 && rise_flag==1'b1)
		oe<=1'b0;
	else if(base_cnt=='d0)
		oe<=1'b0;

always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		r_shift_flag<=1'b0;
	else if(r_flag==1'b1 && base_cnt=='d48 && rise_flag==1'b1)
		r_shift_flag<=1'b1;
	else if(r_flag==1'b1 && end_flag==1'b1)
		r_shift_flag<=1'b0;
					
always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		shift_data<='d0;
	else if(w_en==1'b1 && w_flag==1'b0)
		shift_data<={1'b1,{2'b01},{2'b01},{phy_addr},{reg_addr},{2'b10},{w_data}};
	else if(r_en==1'b1 && r_flag==1'b0)
		shift_data<={1'b1,{2'b01},{2'b10},{phy_addr},{reg_addr},{18'd0}};
	else if(r_shift_flag==1'b1 && fall_flag==1'b1)
		shift_data<={shift_data[31:0],mdio};
	else if(shift_flag==1'b1 && rise_flag==1'b1)
		shift_data<={shift_data[31:0],1'b0};
	else if(r_flag ==1'b0 && w_flag==1'b0)
		shift_data<='d0;
		
always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		rd_v<=1'b0;
	else if(base_cnt == END_NUM && fall_flag==1'b1 && r_flag==1'b1)
		rd_v<=1'b1;
	else rd_v<=1'b0;
		
always @(posedge sclk or negedge rst_n)
	if(rst_n==1'b0)
		r_data<='d0;
	else if(base_cnt == END_NUM && fall_flag==1'b1 && r_flag==1'b1)
		r_data<=shift_data[15:0];
		
assign	mdio=oe?shift_data[32]:1'bz;


endmodule